<?php

namespace app\services;

use app\payment\PayFactory;
use plugin\admin\app\model\Order;
use plugin\admin\app\model\OrderRefund;
use plugin\admin\app\model\OrderRefundLog;
use plugin\admin\app\model\UserPropertyLog;

class OrderRefundService
{
    public static function add($data)
    {
        $order = Order::where('order_no', $data['order_no'])->where('user_id', get_user_id())->first();

        $day = ConfigService::get('apply_after_sales');

        if ($order['receive_time']) {
            if (strtotime('+' . $day . ' days', strtotime($order['receive_time'])) < time()) {
                throw new \Exception('已超出售后期限,无法发起售后申请');
            }
        }

        if (empty($data['refund_images'])) {
            throw new \Exception('请上传退款凭证');
        }

        if ($order['refund_status'] == OrderRefund::AGREE) {
            throw new \Exception('该订单已退款');
        } elseif ($order['refund_status'] == OrderRefund::UNPROCESS) {
            throw new \Exception('申请未处理，请耐心等候');
        }

        $order->refund_amount = $order['price'];
        $order->refund_reason = $data['refund_reason'] ?? '';
        $order->refund_desc = $data['refund_desc'] ?? '';
        $order->refund_status = OrderRefund::UNPROCESS;
        $order->refund_type = $data['refund_type'] ?? 1;
        $order->save();

//        if ($data['refund_amount'] > $order['price']) {
//            throw new \Exception('退款金额不能大于订单金额');
//        }

        $data['status'] = OrderRefund::UNPROCESS;
        $data['user_id'] = get_user_id();
        $data['refund_images'] = json_encode($data['refund_images'], JSON_UNESCAPED_UNICODE);
        $data['created_time'] = date('Y-m-d H:i:s');
        $refundId = OrderRefund::insertGetId($data);

        OrderRefundLog::insert([
            'refund_id' => $refundId,
            'status' => 0,
            'created_time' => date('Y-m-d H:i:s')
        ]);
    }

    public static function agree($refundId)
    {
        $refundInfo = OrderRefund::where('id', $refundId)->first();

        $refundInfo->status = OrderRefund::AGREE;
        $refundInfo->agree_time = date('Y-m-d H:i:s');
        $refundInfo->save();

        $orderInfo = Order::where('order_no', $refundInfo['order_no'])->first();
        $orderInfo['refund_status'] = OrderRefund::AGREE;
        $orderInfo['refund_type'] = $refundInfo['refund_type'];
        $orderInfo['refund_reason'] = $refundInfo['refund_reason'];
        $orderInfo['refund_amount'] = $refundInfo['refund_amount'];
        $orderInfo['refund_desc'] = $refundInfo['refund_desc'];
        $orderInfo['refund_images'] = $refundInfo['refund_images'];
        $orderInfo['status'] = Order::STATUS_AFTER_SALES;
        $orderInfo->save();

        OrderRefundLog::insert([
            'refund_id' => $refundId,
            'status' => OrderRefund::AGREE,
            'created_time' => date('Y-m-d H:i:s')
        ]);

        $info = json_decode($orderInfo['info'], true);

        $count = count($info['personInfos']);
        ActivityService::decrementCount($orderInfo['activity_id'], $count);
    }

    public static function backProperty($refundId)
    {
        $refundInfo = OrderRefund::where('id', $refundId)->first();

        $datetime = date('Y-m-d H:i:s');

        $orderInfo = Order::where('order_no', $refundInfo['order_no'])->first();
        $orderInfo['refund_status'] = OrderRefund::BACK;
        $orderInfo['back_time'] = $datetime;
        $orderInfo->save();

        if (!empty($orderInfo['coupon_id'])) {
            UserCouponService::back($orderInfo['coupon_id']);
        }

        OrderRefundLog::insert([
            'refund_id' => $refundInfo['id'],
            'status' => OrderRefund::BACK,
            'created_time' => $datetime
        ]);

        $refundInfo->back_time = $datetime;
        $refundInfo->status = OrderRefund::BACK;
        $refundInfo->save();

        PayFactory::create($orderInfo['pay_way'])->setData(['total_amount' => $refundInfo['refund_amount'], 'user_id' => $orderInfo['user_id'], 'source' => UserPropertyLog::ORDER_PAY_BACK, 'order_no' => $refundInfo['order_no']])->payBack();
    }

    public static function reject($refundId, $reason = '', $desc = '')
    {
        $refundInfo = OrderRefund::where('id', $refundId)->first();

        $refundInfo->status = OrderRefund::REJECT;
        $refundInfo->reject_reason = $reason;
        $refundInfo->reject_desc = $desc;
        $refundInfo->save();

        $orderInfo = Order::where('order_no', $refundInfo['order_no'])->first();
        $orderInfo['refund_status'] = OrderRefund::REJECT;
        $orderInfo->save();

        OrderRefundLog::insert([
            'refund_id' => $refundId,
            'status' => OrderRefund::REJECT,
            'created_time' => date('Y-m-d H:i:s')
        ]);
    }

    public static function cancel($data)
    {
        $order = Order::where('order_no', $data['order_no'])->where('user_id', get_user_id())->first();

        if ($order['refund_status'] == 1) {
            $order->refund_status = OrderRefund::CANCEL;
            $order->save();

            $orderRefund = OrderRefund::where('order_no', $data['order_no'])->where('status', OrderRefund::UNPROCESS)->first();
            $orderRefund->status = OrderRefund::CANCEL;
            $orderRefund->save();

            OrderRefundLog::insert([
                'refund_id' => $orderRefund['id'],
                'status' => OrderRefund::CANCEL,
                'created_time' => date('Y-m-d H:i:s')
            ]);
        }
    }

    public static function setRefundExpress($orderNo, $expressNo, $expressCompany)
    {
        $refund = OrderRefund::where('order_no', $orderNo)->where('user_id', get_user_id())->orderByDesc('id')->first();

        if (!$refund) {
            throw new \Exception('不存在的售后订单');
        }

        if ($refund['status'] != OrderRefund::AGREE) {
            throw new \Exception('该申请未审核通过');
        }

        $refund->refund_express_no = $expressNo;
        $refund->refund_express_company = $expressCompany;
        $refund->save();
    }

    public static function getRefundTypeText($refundType)
    {
        return $refundType == 1 ? '仅退款' : '退款退货';
    }

}